﻿using Infrastructure.ElasticSearch.Enums;
using Nest;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace Infrastructure.ElasticSearch.Nests
{
    public class ElasticSearchNestRoot<T> where T : class
    {
        private SearchDescriptor<T> _container;
        private List<ElasticSearchSort<T>> _sorts;

        public SearchDescriptor<T> SearchContainer { get { return _container; } }

        public bool IsPage { get; private set; }
        public int Page { get; private set; }
        public int PageSize { get; private set; }
        public bool IsSearchTotal { get; private set; }

        public ElasticSearchNestRoot(SearchDescriptor<T> container)
        {
            _container = container;
            _sorts = new List<ElasticSearchSort<T>>();
        }

        /// <summary>
        /// 添加分页
        /// </summary>
        /// <param name="page"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        public ElasticSearchNestRoot<T> AddPage(int page, int size, int begin)
        {
            size = size <= 0 ? 10 : size;
            page = begin > 0 ? begin : (page <= 1 ? 0 : (page - 1) * size);

            IsPage = true;
            this.Page = page;
            this.PageSize = size;

            return this;
        }

        /// <summary>
        /// 是否计算总数
        /// </summary>
        /// <param name="trackTotalHit"></param>
        /// <returns></returns>
        public ElasticSearchNestRoot<T> AddTrackTotal(bool trackTotalHit = false)
        {
            IsSearchTotal = trackTotalHit;

            return this;
        }

        /// <summary>
        /// 添加排序
        /// </summary>
        /// <param name="field"></param>
        /// <param name="order"></param>
        /// <returns></returns>
        public ElasticSearchNestRoot<T> AddSort(Expression<Func<T, object>> field, QueryOrderTypeEnum order = QueryOrderTypeEnum.Asc)
        {
            _sorts.Add(new ElasticSearchSort<T>(field, order));

            return this;
        }

        public void BuildQuery()
        {
            //分页
            if (IsPage)
            {
                _container.From(Page).Size(PageSize);
            }

            //排序
            var sort = BuildSort();
            if (sort != null)
            {
                _container.Sort(sort);
            }

            //查询总数
            _container.TrackTotalHits(IsSearchTotal);

        }

        private Func<SortDescriptor<T>, IPromise<IList<ISort>>> BuildSort()
        {
            if (_sorts != null && _sorts.Any())
            {
                return (s) =>
                {
                    foreach (var sort in _sorts)
                    {
                        if (sort.Order == QueryOrderTypeEnum.Asc)
                            s.Ascending(sort.Field);
                        else
                            s.Descending(sort.Field);
                    }
                    return s;
                };
            }
            return null;
        }

    }
}
